This page last changed on Oct 30, 2006 by andrew.

There is now no need to write Spring Bean configurations for Mule yourself as Mule can autogenerate Spring Bean Xml from Mule Xml. See Configuring a Spring context using Mule Xml for more information.

It is still possible to configure Mule in the ways described below and this page is left here for reference.

The MuleManager can be created directly from a Spring context. This means you can distribute your MuleManager as a Spring applicationContext.xml file. Mule provides a Spring FactoryBean for creating the MuleManager instance, there are two implementations -

  1. org.mule.extras.spring.config.UMOManagerFactoryBean. It expects that every bean for the MuleManager to be wired explicitly in the Spring configuration. (The factory Bean is Deprecated)
  2. org.mule.extras.spring.config.AutowireUMOManagerFactoryBean. It expects that all beans such as connectors, provders, component descriptors are declared in the configuration, but will then 'autowire' the MuleManager together based on what is available in the application context. This FactoryBean is more useful that the other as it can be a bit of an effort to wire the MuleManager together manually.

Many objects in Mule, such as connectors, transformers and managed components have a unique name attribute that must be set. Most of the time the Spring bean id will be the same as the name for the Mule object so you can get Spring to set the bean id's to Mule object names by declaring the MuleObjectNameProcessor bean in the container -

<bean id="muleNameProcessor" class="org.mule.extras.spring.config.MuleObjectNameProcessor"/>

Using AutowireUMOManagerFactoryBean

In order yo use the AutowireUMOManagerFactoryBean you must define a muleManager bean as an instance of org.mule.extras.spring.config.AutowireUMOManagerFactoryBean. The name of the bean is not important to Mule. This factory bean is responsible for determining the instance type of UMOManager to create and then delegates configuration calls to that instance depending on what is available in the container.

<bean id="muleManager" class="org.mule.extras.spring.config.AutowireUMOManagerFactoryBean"/>

Apart from removing the need to explicitly wire the MuleManager instance together there another advantage to using the AutowireUMOManagerFactoryBean. There is no need to declare a UMOModel instance in the configuration. If the factory doesn't find a UMOModel implementation it creates a default one of type org.mule.impl.model.MuleModel. The model is automatically initialised with a SpringComponentResolver using the current applicationContext and defaults are used for the other Model properties. If you want to override the defaults, such as define your own exception strategy, (which you will most likely want to do) simply declare your exception strategy bean in the container and it will automatically be set on the model.

Mule requires a manager ID be available if JMX management is in use (since Mule 1.3.1). You can set the managerId property on this factory bean to configure it.

Most Mule objects have explicit types and can be autowired, however some objects cannot be autowired, such as a java.util.Mapof endpoints for example. For these objects Mule defines standard bean names that will be looked for in the container during start up.
muleEnvironmentProperties
A map of properties to set on the MuleManager. Accessible from your code using AutowireUMOManagerFactoryBean.MULE_ENVIRONMENT_PROPERTIES_BEAN_NAME.
muleEndpointMappings
A Map of logical endpoint mappings accessible from your code using
AutowireUMOManagerFactoryBean.MULE_ENDPOINT_MAPPINGS_BEAN_NAME.
muleInterceptorStacks
A map of interceptotor stacks, where the name of the stack is the key and a list of interceptors is the value. Accessible using from your code using AutowireUMOManagerFactoryBean.MULE_INTERCEPTOR_STACK_BEAN_NAME. An example interceptor stack configuration might look like this-

<bean id="defaultInterceptorStack" class="java.util.ArrayList">
        <constructor-arg>
            <list>
                <ref local="loggingInterceptor"/>
                <ref local="timerInterceptor"/>
            </list>
        </constructor-arg>
    </bean>

    <bean id="muleInterceptorStacks" class="java.util.HashMap">
        <constructor-arg>
            <map>
                <entry key="default"><ref local="defaultInterceptorStack"/></entry>
            </map>
        </constructor-arg>
    </bean>

Using UMOManagerFactoryBean

Configuration with the UMOManagerFactoryBean is more involved but is sometimes useful when testing as you explicitly control what objects are configured on the MuleManager. In order to use it you must define a muleManager bean as an instance of org.mule.extras.spring.UMOManagerFactoryBean. Again, the name of the bean is not important. This is a factory bean that creates a MuleManager instance (or deriving type) and then delegates configuration calls to that instance. Each of the dependencies of the MuleManager must be defined explicitly in the configuration.

<bean id="muleManager" class="org.mule.extras.spring.config.UMOManagerFactoryBean">
        <property name="configuration"><ref local="muleConfiguration"/></property>
        <property name="messageEndpoints"><ref local="messageEndpoints"/></property>
        <property name="connectors"><ref local="connectorList"/></property>
        <property name="transformers"><ref local="transformerList"/></property>
        <property name="endpoints"><ref local="endpointList"/></property>
        <property name="interceptorStacks"><ref local="interceptorsMap"/></property>
        <property name="model"><ref local="model"/></property>
 </bean>

Some of the properties of the bean as local references to java.util.List and java.util.Map beans in the container, if you do not want these collection objects floating around in your container you can always declare each property as a <list> or <map> and add the bean refs inline. For example, the endpoints are declared 'inline' negating the need to declare a endpointList bean in your applicationContext.xml.

<bean id="muleManager" class="org.mule.config.spring.config.UMOManagerFactoryBean">
        <property name="configuration"><ref local="muleConfiguration"/></property>
        <property name="messageEndpoints"><ref local="messageEndpoints"/></property>
        <property name="connectors"><ref local="connectorList"/></property>
        <property name="transformers"><ref local="transformerList"/></property>
        <property name="endpoints">
            <list>
                <ref local="globalInboundJmsEndpoint"/>
                <ref local="globalOutboundJmsEndpoint"/>
                <ref local="globalHttpEndpoint"/>
           </list>
        </property>
        <property name="interceptorStacks"><ref local="interceptorsMap"/></property>
        <property name="model"><ref local="model"/></property>
 </bean>

For more information about configuring the Spring Application Context you can go to the Spring web site.

Configuring Mule objects in Spring

By default, Spring creates all bean instances as singletons, that is only one bean instance is created and the same instance is returned for each request of that bean. This is fine for most of the Mule server objects but there are three important exceptions -

  1. Objects that are managed by Mule. Mule managed objects cannot be singletons because components are pooled and each pooled instance is expected to be different.
  2. Mule Endpoints. Endpoints are Mutable and can be global meaning that more than one component can reference the same instance. It is feasible that users of the same endpoint might want to update the endpoint or properties as runtime. Initialising the endpoints as a singleton would mean those changes would affect all other components referencing the same endpoint.
  3. Mule Transformers. For the same reasons as endpoints, transformers should not be singletons.

Mule Component Configuration

Configuring a Mule managed component in Spring is very similar to configuring a component in the Mule Xml configuration.
Notice here that the implementationattribute of the testComponent bean is set to <value>myPojo</value> and not to <local ref="myPojo"/>. This is because at runtime Mule will look up a bean in the context with the name 'myPojo' and may do so several times depending on the component pooling settings.

<bean id="testComponent" class="org.mule.impl.MuleDescriptor">
        <property name="name"><value>testComponent</value></property>
        <property name="inboundEndpoint>
            <bean class="org.mule.impl.endpoint.MuleEndpointURI">
                <constructor-arg index="0">
                    <value>vm://test.queue</value>
                </constructor-arg>
            </bean>
        </property>
        <property name="outboundEndpoint">
           <bean class="org.mule.impl.endpoint.MuleEndpointURI">
                <constructor-arg index="0">
                    <value>vm://out.queue</value>
                </constructor-arg>
            </bean>
        </property>
        <property name="implementation"><value>myPojo</value></property>
        <property name="interceptors">
            <list>
                <ref local="loggingInterceptor"/>
            </list>
        </property>
        <property name="messageRouter"><ref local="testMessageRouter"/></property>
   </bean>

   <bean id="myPojo" class="org.foo.bar.Pojo" singleton='false'/>

Configuration Example

Below is a simple but complete configuration for Mule. It defines a single managed component 'orderProcessor' and an inbound and outbound jms endpoint, a couple of jms transformers and some endpoint mappings. This example uses the AutowireUMOManagerFactoryBean and no model is defined so a default one will be created. Notice that the orderProcessorDescriptor and endpoints are not singletons.

<beans>
    <bean id="muleManager"
       class="org.mule.extras.spring.config.AutowireUMOManagerFactoryBean"/>

    <bean id="muleNameProcessor"
       class="org.mule.extras.spring.config.MuleObjectNameProcessor"/>

    <bean id="jmsConnector" className="org.mule.providers.jms.JmsConnector">
        <property name="acknowledgementMode"><value>1</value></property>
        <!-- The name of a JMS connection factory to use -->
        <property name="connectionFactoryJndiName">
            <value>JmsQueueConnectionFactory</value>
        </property>
        <property name="jndiProviderProperties">
            <map>
                <entry key="java.naming.factory.initial">
                    <value>org.exolab.jms.jndi.InitialContextFactory</value>
                </entry>
                <entry key="java.naming.provider.url">
                    <value>tcp://localhost:3035</value>
                </entry>
            </map>
        </property>
    </bean>

    <bean id="StringToJmsMessage" singleton="false"
        class="org.mule.providers.jms.transformers.ObjectToJMSMessage">
        <property name="returnClass"><value>javax.jms.TextMessage</value></property>
        <property name="doCompression"><value>true</value></property>
    </bean>

    <bean id="JmsMessageToString" singleton="false"
        class="org.mule.providers.jms.transformers.JMSMessageToObject">
        <property name="returnClass"><value>java.lang.String</value></property>
        <property name="doCompression"><value>true</value></property>
    </bean>

    <bean id="muleEndpointMappings" class="java.util.HashMap">
        <constructor-arg>
            <map>
                <entry key="Orders Queue"><value>customer.orders.in</value></entry>
	       <entry key="Feedback Queue"><value>customer.feedback.out</value></entry>
            </map>
        </constructor-arg>
    </bean>

    <bean id="customerOrdersEndpoint" singleton="false"
        class="org.mule.impl.endpoint.MuleEndpoint">
        <property name="connector"><ref local="jmsConnector"/></property>
        <property name="endpointURI">
            <bean class="org.mule.impl.endpoint.MuleEndpointURI">
                <constructor-arg index="0">
                    <value>jms://test.queue</value>
                </constructor-arg>
            </bean>
        </property>
        <property name="transformers"><value>JmsMessageToString</value></property>
        <property name="type"><value>receiver</value></property>
    </bean>

    <bean id="customerFeedbackEndpoint" singleton="false"
        class="org.mule.impl.endpoint.MuleEndpoint">
        <property name="connector"><ref local="jmsConnector"/></property>
        <property name="endpointURI">
            <bean class="org.mule.impl.endpoint.MuleEndpointURI">
                <constructor-arg index="0">
                    <value>jms://feedback.queue</value>
                </constructor-arg>
            </bean>
        </property>
        <property name="transformers"><value>StringToJmsMessage</value></property>
        <property name="type"><value>sender</value></property>
    </bean>

    <bean id="orderProcessorDescriptor" class="org.mule.impl.MuleDescriptor">
        <property name="inboundEndpoint">
            <ref local="customerOrdersEndpoint"/>
        </property>
        <property name="outboundEndpoint">
            <ref local="customerFeedbackEndpoint"/>
        </property>
        <property name="implementation">
            <value>orderProcessor</value>
        </property>
   </bean>

   <bean id="orderProcessor" class="org.foo.bar.OrderManager" singleton='false'/>
</beans>

Overloading the MuleManager in Spring

By default, The Spring Mule factories create an instance of org.mule.MuleManager. You can override the type of manager created by setting the org.mule.umo.UMOManager system property to a fully qualified class name to use.

-Dorg.mule.umo.UMOManager=com.foo.MyMuleManager

or from code before you configure the MuleManager -

System.setProperty("org.mule.umo.UMOManager", "com.foo.MyMuleManager");

SpringConfigurationBuilder builder = new SpringConfigurationBuilder();
MyMuleManager manager = (MyMuleManager)builder.configure("applicationContext.xml");

Note that com.foo.MyMuleManager would need to implement org.mule.umo.UMOManager or extend org.mule.MuleManager and that to access your instance of UMOManager you still call MuleManager.getInstance().

Here is a sample configuration for starting Mule from Spring posted to the users list by Conal Markey:

I start Mule from Spring in the following way.
I have a file called muleContext.xml with the following entries;

<bean id="muleManager" class="org.mule.extras.spring.config.AutowireUMOManagerFactoryBean" destroy-method="dispose" singleton="true"/>

    <!-- Used to set mule object names to their corresponding bean id -->
    <bean id="muleNameProcessor" class="org.mule.extras.spring.config.MuleObjectNameProcessor"/>

        <!-- The mule client we will use to send events to the mule server -->
    <bean id="muleClient" class="org.mule.extras.client.MuleClient" depends-on="muleManager"/>

I then added this context file to the appropriate context parameter in the web.xml. (If its not a web app you have then you should be able to just add this to the list of config files you give the relevant application context builder).

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
                classpath:com/.../.../config/muleContext.xml

The autowire manager then picks up all the other classes in my context files of mule types.

One thing to watch, I had significant problems with the instance of MuleClient being created before the MuleManger because I was injecting this to other beans, (the depends-on attribute I have in the config above doesn't do what it suggests). I had to remove the references to the MuleClient from other context files to get round this.

Hope this helps

Document generated by Confluence on Nov 27, 2006 10:27